package cn.cms.controller;

import cn.cms.annotation.SystemLogAnno;
import cn.cms.constants.Constants;
import cn.cms.dao.PageDao;
import cn.cms.dao.SysLogDao;
import cn.cms.model.SysLog;
import cn.cms.model.SysRole;
import cn.cms.model.SysUser;
import cn.cms.service.SysRoleService;
import cn.cms.service.SysUserService;
import cn.cms.util.DateUtil;
import cn.cms.util.ResponseUtil;
import cn.cms.util.SessionUtil;
import cn.cms.util.StringUtil;
import cn.cms.webcommon.LocalContextFactory;
import cn.cms.webcommon.ReqBo;
import cn.cms.webcommon.ResBo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.perf4j.LoggingStopWatch;
import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Created by justin on 2017/12/15.
 */
@Controller
@RequestMapping(value = "sysuser")
public class SysUserController extends AbstractController {

    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysRoleService sysRoleService;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
//    @SystemLog(operationType = SystemLog.LOGIN, operationName = "正常登录系统")
    public String login(HttpServletRequest request, HttpServletResponse response,
                        Model model,
                        @RequestParam(value = "userName", required = false) String userName,
                        @RequestParam(value = "userPassword", required = false) String userPassword) {
        StopWatch stopWatch = new LoggingStopWatch();

        String requestMethod = request.getMethod();
        if ("POST".equals(requestMethod)) {
            ReqBo reqBo = new ReqBo();
            reqBo.addParam("userName", userName);
            reqBo.addParam("userPassword", userPassword);
            ResBo resBo = sysUserService.login(reqBo);
            SysUser loginUser = null;
            if (!resBo.isSuccess()) {// 登录不成功
                model.addAttribute("errMsg", resBo.getErrMsg());
                return "sysuser/login";
            } else {// 登录成功
                loginUser = (SysUser) resBo.getResult("sysUser");
            }
            // 验证通过获得登录信息
            loginUser.setLoginDate(new Date());
            // 保存登录信息到session
            SessionUtil.setAttribute(request, Constants.SESSION_KEY, loginUser);
            // 保存登录日志
            String sessionId = request.getSession().getId();
            this.saveLoginLog(request, loginUser, sessionId);
            return "redirect:/index";
        }

        stopWatch.stop("adminUser-login");
        return "sysuser/login";
    }

    private void saveLoginLog(HttpServletRequest request, SysUser user, String sessionId) {
        String loginInfo = "正常登录系统(" + sessionId + ")，时间：" + DateUtil.getFormatDate(user.getLoginDate(), "yyyy-MM-dd HH:mm:ss");
        logger.info(loginInfo);
        SysLogDao systemLogDao = LocalContextFactory.getInstance().getBean(SysLogDao.class);
        SysLog systemLog = new SysLog();
        systemLog.setRealName(user.getRealName());
        systemLog.setLoginName(user.getLoginName());
        systemLog.setSrcIp(super.getIpAddr(request));
        systemLog.setDateAdd(new Date());
        systemLog.setName(loginInfo);
        systemLog.setType(SystemLogAnno.LOGIN);
        // 隐去密码
        user.setEncryptedPassword("***");
        user.setPlainPassword("***");
        systemLog.setParams(JSONObject.toJSONString(user));
        // 保存
        systemLogDao.save(systemLog);
    }

    @RequestMapping(value = "/logout")
//    @SystemLog(operationType = SystemLog.LOGOUT, operationName = "正常退出系统")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        // session失效
        request.getSession().invalidate();
        return "sysuser/login";
    }

    /**
     * 列表头
     */
    @RequestMapping(value = "page", method = RequestMethod.POST)
    public String page() {
        return "sysuser/page";
    }


    @RequestMapping(value = "/save")
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.ADDORUPD, operationName = "系统用户-系统用户管理")
    public void save(HttpServletResponse response, HttpServletRequest request, SysUser sysUser) {
        ResBo resBo = new ResBo();
        if (sysUser.getId() == null) {// 增加
            if (sysUserService.register(sysUser)) {
                ResponseUtil.printAjaxPack(response, resBo);
            } else {
                resBo.setSuccess(false);
                resBo.setErrMsg("登录名重复！请重新输入！");
                ResponseUtil.printAjaxPack(response, resBo);
            }
        } else {// 修改
            sysUserService.modify(sysUser);
        }
        ResponseUtil.printAjaxPack(response, resBo);
    }

    @RequestMapping(value = "/list", method = {RequestMethod.POST})
    public String list(HttpServletRequest request, Model model, String keyWords, PageDao pageDao) {
        StopWatch stopWatch = new Slf4JStopWatch("/li22333");

        pageDao.setQueryCondition(super.getQueryCondition(request));
        pageDao.setDivId(super.getDivId(request));
        pageDao.setResult(sysUserService.getListPage(pageDao, keyWords));

        model.addAttribute("pages", pageDao);

        stopWatch.stop("Time of loading system user list");

        return "sysuser/list";
    }

    /**
     * 表单页
     */
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String editPage(SysUser user, Model model) {
        if (user.getId() != null) {
            SysUser sysUser = sysUserService.get(user.getId());
            model.addAttribute("sysUser", sysUser);
        } else {
            model.addAttribute("create", 1);
        }
        return "sysuser/form";
    }

    @RequestMapping(value = "/saveRoles")
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.UPD, operationName = "用户角色-系统用户管理")
    public void saveRoles(HttpServletResponse response, HttpServletRequest request, SysUser sysUser) {
        ResBo resBo = new ResBo();
        String roleIds = sysUser.getRoleIds();
        if (sysUser.getId() == null) {
            resBo.setSuccess(false);
            resBo.setErrMsg("用户不存在！");
            ResponseUtil.printAjaxPack(response, resBo);
        } else {// 修改
            List<Integer> roleIdList = new ArrayList<>();
            SysUser loginUser = SessionUtil.getUserSession(request);
            String[] loginRoleIdss = ((loginUser.getRoleIds() == null) ? "" : loginUser.getRoleIds()).split(",");
            for (String roleId : loginRoleIdss) {
                if (!StringUtil.isSpaceOrNull(roleId)) {
                    roleIdList.add(Integer.valueOf(roleId));
                }
            }
            // 当前登录用户角色最大级别
            int maxLevel = sysRoleService.getMaxLevel(roleIdList);

            roleIdList.clear();
            String[] roleIdsToSave = ((roleIds == null) ? "" : roleIds).split(",");
            for (String roleId : roleIdsToSave) {
                if (!StringUtil.isSpaceOrNull(roleId)) {
                    SysRole sysRole = sysRoleService.getRoleById(Integer.valueOf(roleId));
                    if (sysRole.getLevel() > maxLevel) {
                        roleIdList.add(Integer.valueOf(roleId));
                    }
                }
            }
            StringBuilder sb = new StringBuilder();
            roleIdList.forEach(s -> {
                sb.append(s).append(",");
            });
            if (sb.length() > 0) {
                roleIds = sb.substring(0, sb.length() - 1);
            } else {
                roleIds = sb.toString();
            }
            // 将过滤后的角色ID放入对象
            sysUser.setRoleIds(roleIds);

            sysUserService.modifyRoles(sysUser);
        }
        ResponseUtil.printAjaxPack(response, resBo);
    }

    /**
     * 更改用户角色
     */
    @RequestMapping(value = "/editRoles", method = RequestMethod.POST)
    public String editRoles(SysUser sysUser, Model model) {
        List<String> roleIds = new ArrayList<>();
        sysUser = sysUserService.get(sysUser.getId());
        model.addAttribute("sysUser", sysUser);

        roleIds.addAll(Arrays.asList(((sysUser.getRoleIds() == null) ? "" : sysUser.getRoleIds()).split(",")));
        List<SysRole> sysRoles = sysRoleService.getRoles(roleIds);
        String roleIdstr = sysRoleService.getCheckedRoleIds(sysRoles);
        // 清洗数据
        sysUser.setRoleIds(roleIdstr);
        model.addAttribute("roles_json", JSON.toJSON(sysRoles));
        return "sysuser/roles_tree";
    }


    /**
     * 密码表单页
     */
    @RequestMapping(value = "pwdform", method = RequestMethod.POST)
    public String pwdform(SysUser sysUser, HttpServletResponse response) {
        return "sysuser/pwdform";
    }


    /**
     * 修改密码
     */
    @RequestMapping(value = "chgpwd", method = RequestMethod.POST)
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.DEL, operationName = "系统用户密码-系统用户管理")
    public void chgpwd(HttpServletRequest request, HttpServletResponse response, SysUser sysUser) {
        ReqBo reqBo = new ReqBo();
        reqBo.addParam("sysUser", sysUser);
        ResBo resBo = sysUserService.chgPwd(reqBo);
        if (resBo.isSuccess()) {// 成功修改密码，清除session信息
            SessionUtil.removeAttribute(request, Constants.SESSION_KEY);
        }
        ResponseUtil.printAjaxPack(response, resBo);
    }

    /**
     * 删除
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.DEL, operationName = "系统用户-系统用户管理")
    public void delete(HttpServletResponse response, SysUser sysUser) {
        ResBo resBo = new ResBo();
        if (sysUser.getId() != null) {
            sysUserService.delete(sysUser);
        } else {
            resBo.setSuccess(false);
            resBo.setErrMsg("该项不存在或已经删除！");
        }
        ResponseUtil.printAjaxPack(response, resBo);
    }


    /**
     * 重置密码
     */
    @RequestMapping(value = "resetPwd", method = RequestMethod.POST)
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.UPD, operationName = "重置用户密码-系统用户管理")
    public void resetPwd(HttpServletResponse response, SysUser sysUser) {
        ResBo resBo = new ResBo();
        if (sysUser.getId() != null) {
            resBo = sysUserService.resetPwd(sysUser);
        } else {
            resBo.setSuccess(false);
            resBo.setErrMsg("该项不存在或已经删除！");
        }
        ResponseUtil.printAjaxPack(response, resBo);
    }

    /**
     * 修改生失效状态
     */
    @RequestMapping(value = "/changeState", method = RequestMethod.POST)
    @ResponseBody
    @SystemLogAnno(operationType = SystemLogAnno.UPD, operationName = "系统用户状态-系统用户管理")
    public void changeState(HttpServletResponse response, Long id) {
        SysUser sysUser = sysUserService.get(id);
        if (sysUser != null) {
            if (SysUser.STATE_ON.equals(sysUser.getState())) {
                sysUser.setState(SysUser.STATE_OFF);
            } else {
                sysUser.setState(SysUser.STATE_ON);
            }
            sysUserService.update(sysUser);
        }

        ResBo resBo = new ResBo();
        ResponseUtil.printAjaxPack(response, resBo);
    }

}
